package 简单.其他;

/**
 * 给你一个整数 x ，如果 x 是一个回文整数，返回 true ；否则，返回 false 。
 * <p>
 * 回文数是指正序（从左向右）和倒序（从右向左）读都是一样的整数。例如，121 是回文，而 123 不是。
 * <p>
 * 来源：https://leetcode-cn.com/problems/palindrome-number/
 */
public class 回文数_9 {

    public static void main(String[] args) {

        int x = 1221;
        boolean palindrome = efficientIsPalindrome(x);
        System.out.println(palindrome);

    }

    //将数字变成数组，判断最后一个和第一个值是否相等，逐渐向中间靠拢
    public static boolean isPalindrome1(int x) {
        char[] chars = String.valueOf(x).toCharArray();
        if (chars.length == 1) {
            return true;
        }
        if (chars.length == 2) {
            if (chars[0] != chars[1]) {
                return false;
            }
        }
        if (chars.length == 3) {
            if (chars[0] != chars[2]) {
                return false;
            }
        }
        int left = 0;
        int right = chars.length - 1;
        if (chars.length % 2 == 0) {
            while ((right - left) > 0) {
                if (chars[left] != chars[right]) {
                    return false;
                }
                --right;
                ++left;
            }
        } else {
            while ((right - left) > 1) {
                if (chars[left] != chars[right]) {
                    return false;
                }
                --right;
                ++left;
            }
        }
        return true;
    }

    //将字符串反转，再判断
    public static boolean isPalindrome2(int x) {
        String s = String.valueOf(x);
        String s1 = new StringBuffer(s).reverse().toString();
        if (s == s1) {
            return true;
        }
        return false;
    }

    //根据%和/得到首末位的数
    public static boolean isPalindrome3(int x) {
        //边界判断
        if (x < 0) return false;
        int div = 1;
        //取得和参数相同位数的10的倍数数
        while (x / div >= 10) div *= 10;
        while (x > 0) {
            //得到末位数
            int left = x / div;
            //得到首位数
            int right = x % 10;
            if (left != right) return false;
            //%div是去除末位数，/10是去除首位数,1221 ==> 22
            x = (x % div) / 10;
            div /= 100;
        }
        return true;
    }

    //反转一半,如果该数字是回文，其后半部分反转后应该与原始数字的前半部分相同。
    public static boolean efficientIsPalindrome(int x) {

        // 因为 - 不等于 3。所以我们可以对所有负数返回 false。除了 0 以外，所有个位
        // 是 0 的数字不可能是回文，因为最高位不等于 0。所以我们可以对所有大于 0 且个位是 0 的数字返回 false。
        if (x < 0 || (x % 10 == 0 && x != 0)) {
            return false;
        }

        int revertedNumber = 0;
        //当前部分的数字小于或等于后部分数字时停止循环
        while (x > revertedNumber) {
            //0 ==> 0*10+1221%10=1 ==> 1*10+122%10=12
            revertedNumber = revertedNumber * 10 + x % 10;
            //去除首位，1221 ==> 122 ==> 12
            x /= 10;
        }

        //位数是奇数时x == revertedNumber / 10，是偶数时前部分等于后部分
        return x == revertedNumber || x == revertedNumber / 10;
    }

}
